Line data Source code
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 : #include "webrtc/voice_engine/channel_proxy.h"
28 :
29 : //Some WebRTC types for short notations
30 : using webrtc::VoEBase;
31 : using webrtc::VoENetwork;
32 : using webrtc::VoECodec;
33 : using webrtc::VoEExternalMedia;
34 : using webrtc::VoEAudioProcessing;
35 : using webrtc::VoEVideoSync;
36 : using webrtc::VoERTP_RTCP;
37 : /** This file hosts several structures identifying different aspects
38 : * of a RTP Session.
39 : */
40 : namespace mozilla {
41 : // Helper function
42 :
43 : DOMHighResTimeStamp
44 : NTPtoDOMHighResTimeStamp(uint32_t ntpHigh, uint32_t ntpLow);
45 :
46 : /**
47 : * Concrete class for Audio session. Hooks up
48 : * - media-source and target to external transport
49 : */
50 : class WebrtcAudioConduit: public AudioSessionConduit
51 : , public webrtc::Transport
52 : {
53 : public:
54 : //VoiceEngine defined constant for Payload Name Size.
55 : static const unsigned int CODEC_PLNAME_SIZE;
56 :
57 : /**
58 : * APIs used by the registered external transport to this Conduit to
59 : * feed in received RTP Frames to the VoiceEngine for decoding
60 : */
61 : virtual MediaConduitErrorCode ReceivedRTPPacket(const void *data, int len, uint32_t ssrc) override;
62 :
63 : /**
64 : * APIs used by the registered external transport to this Conduit to
65 : * feed in received RTCP Frames to the VoiceEngine for decoding
66 : */
67 : virtual MediaConduitErrorCode ReceivedRTCPPacket(const void *data, int len) override;
68 :
69 : virtual MediaConduitErrorCode StopTransmitting() override;
70 : virtual MediaConduitErrorCode StartTransmitting() override;
71 : virtual MediaConduitErrorCode StopReceiving() override;
72 : virtual MediaConduitErrorCode StartReceiving() override;
73 :
74 : /**
75 : * Function to configure send codec for the audio session
76 : * @param sendSessionConfig: CodecConfiguration
77 : * @result: On Success, the audio engine is configured with passed in codec for send
78 : * On failure, audio engine transmit functionality is disabled.
79 : * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting
80 : * transmission sub-system on the engine.
81 : */
82 : virtual MediaConduitErrorCode ConfigureSendMediaCodec(const AudioCodecConfig* codecConfig) override;
83 : /**
84 : * Function to configure list of receive codecs for the audio session
85 : * @param sendSessionConfig: CodecConfiguration
86 : * @result: On Success, the audio engine is configured with passed in codec for send
87 : * Also the playout is enabled.
88 : * On failure, audio engine transmit functionality is disabled.
89 : * NOTE: This API can be invoked multiple time. Invoking this API may involve restarting
90 : * transmission sub-system on the engine.
91 : */
92 : virtual MediaConduitErrorCode ConfigureRecvMediaCodecs(
93 : const std::vector<AudioCodecConfig* >& codecConfigList) override;
94 : /**
95 : * Function to enable the audio level extension
96 : * @param enabled: enable extension
97 : */
98 : virtual MediaConduitErrorCode EnableAudioLevelExtension(bool enabled, uint8_t id) override;
99 :
100 : /**
101 : * Register External Transport to this Conduit. RTP and RTCP frames from the VoiceEngine
102 : * shall be passed to the registered transport for transporting externally.
103 : */
104 : virtual MediaConduitErrorCode SetTransmitterTransport(RefPtr<TransportInterface> aTransport) override;
105 :
106 : virtual MediaConduitErrorCode SetReceiverTransport(RefPtr<TransportInterface> aTransport) override;
107 :
108 : /**
109 : * Function to deliver externally captured audio sample for encoding and transport
110 : * @param audioData [in]: Pointer to array containing a frame of audio
111 : * @param lengthSamples [in]: Length of audio frame in samples in multiple of 10 milliseconds
112 : * Ex: Frame length is 160, 320, 440 for 16, 32, 44 kHz sampling rates
113 : respectively.
114 : audioData[] should be of lengthSamples in size
115 : say, for 16kz sampling rate, audioData[] should contain 160
116 : samples of 16-bits each for a 10m audio frame.
117 : * @param samplingFreqHz [in]: Frequency/rate of the sampling in Hz ( 16000, 32000 ...)
118 : * @param capture_delay [in]: Approx Delay from recording until it is delivered to VoiceEngine
119 : in milliseconds.
120 : * NOTE: ConfigureSendMediaCodec() SHOULD be called before this function can be invoked
121 : * This ensures the inserted audio-samples can be transmitted by the conduit
122 : *
123 : */
124 : virtual MediaConduitErrorCode SendAudioFrame(const int16_t speechData[],
125 : int32_t lengthSamples,
126 : int32_t samplingFreqHz,
127 : int32_t capture_time) override;
128 :
129 : /**
130 : * Function to grab a decoded audio-sample from the media engine for rendering
131 : * / playoutof length 10 milliseconds.
132 : *
133 : * @param speechData [in]: Pointer to a array to which a 10ms frame of audio will be copied
134 : * @param samplingFreqHz [in]: Frequency of the sampling for playback in Hertz (16000, 32000,..)
135 : * @param capture_delay [in]: Estimated Time between reading of the samples to rendering/playback
136 : * @param lengthSamples [out]: Will contain length of the audio frame in samples at return.
137 : Ex: A value of 160 implies 160 samples each of 16-bits was copied
138 : into speechData
139 : * NOTE: This function should be invoked every 10 milliseconds for the best
140 : * peformance
141 : * NOTE: ConfigureRecvMediaCodec() SHOULD be called before this function can be invoked
142 : * This ensures the decoded samples are ready for reading and playout is enabled.
143 : *
144 : */
145 : virtual MediaConduitErrorCode GetAudioFrame(int16_t speechData[],
146 : int32_t samplingFreqHz,
147 : int32_t capture_delay,
148 : int& lengthSamples) override;
149 :
150 :
151 : /**
152 : * Webrtc transport implementation to send and receive RTP packet.
153 : * AudioConduit registers itself as ExternalTransport to the VoiceEngine
154 : */
155 : virtual bool SendRtp(const uint8_t* data,
156 : size_t len,
157 : const webrtc::PacketOptions& options) override;
158 :
159 : /**
160 : * Webrtc transport implementation to send and receive RTCP packet.
161 : * AudioConduit registers itself as ExternalTransport to the VoiceEngine
162 : */
163 : virtual bool SendRtcp(const uint8_t *data,
164 : size_t len) override;
165 :
166 0 : virtual uint64_t CodecPluginID() override { return 0; }
167 0 : virtual void SetPCHandle(const std::string& aPCHandle) {}
168 :
169 0 : explicit WebrtcAudioConduit():
170 : mVoiceEngine(nullptr),
171 : mTransportMonitor("WebrtcAudioConduit"),
172 : mTransmitterTransport(nullptr),
173 : mReceiverTransport(nullptr),
174 : mEngineTransmitting(false),
175 : mEngineReceiving(false),
176 : mChannel(-1),
177 : mDtmfEnabled(false),
178 : mCodecMutex("AudioConduit codec db"),
179 : mCaptureDelay(150),
180 : mLastTimestamp(0),
181 : mSamples(0),
182 0 : mLastSyncLog(0)
183 : {
184 0 : }
185 :
186 : virtual ~WebrtcAudioConduit();
187 :
188 : MediaConduitErrorCode Init();
189 :
190 0 : int GetChannel() { return mChannel; }
191 0 : webrtc::VoiceEngine* GetVoiceEngine() { return mVoiceEngine; }
192 :
193 : /* Set Local SSRC list.
194 : * Note: Until the refactor of the VoE into the call API is complete
195 : * this list should contain only a single ssrc.
196 : */
197 : bool SetLocalSSRCs(const std::vector<unsigned int>& aSSRCs) override;
198 : std::vector<unsigned int> GetLocalSSRCs() const override;
199 0 : bool SetRemoteSSRC(unsigned int ssrc) override
200 : {
201 0 : return false;
202 : }
203 : bool GetRemoteSSRC(unsigned int* ssrc) override;
204 : bool SetLocalCNAME(const char* cname) override;
205 :
206 : bool GetSendPacketTypeStats(
207 : webrtc::RtcpPacketTypeCounter* aPacketCounts) override;
208 :
209 : bool GetRecvPacketTypeStats(
210 : webrtc::RtcpPacketTypeCounter* aPacketCounts) override;
211 :
212 0 : bool GetVideoEncoderStats(double* framerateMean,
213 : double* framerateStdDev,
214 : double* bitrateMean,
215 : double* bitrateStdDev,
216 : uint32_t* droppedFrames,
217 : uint32_t* framesEncoded) override
218 : {
219 0 : return false;
220 : }
221 0 : bool GetVideoDecoderStats(double* framerateMean,
222 : double* framerateStdDev,
223 : double* bitrateMean,
224 : double* bitrateStdDev,
225 : uint32_t* discardedPackets,
226 : uint32_t* framesDecoded) override
227 : {
228 0 : return false;
229 : }
230 : bool GetAVStats(int32_t* jitterBufferDelayMs,
231 : int32_t* playoutBufferDelayMs,
232 : int32_t* avSyncOffsetMs) override;
233 : bool GetRTPStats(unsigned int* jitterMs, unsigned int* cumulativeLost) override;
234 : bool GetRTCPReceiverReport(DOMHighResTimeStamp* timestamp,
235 : uint32_t* jitterMs,
236 : uint32_t* packetsReceived,
237 : uint64_t* bytesReceived,
238 : uint32_t *cumulativeLost,
239 : int32_t* rttMs) override;
240 : bool GetRTCPSenderReport(DOMHighResTimeStamp* timestamp,
241 : unsigned int* packetsSent,
242 : uint64_t* bytesSent) override;
243 :
244 : bool SetDtmfPayloadType(unsigned char type, int freq) override;
245 :
246 : bool InsertDTMFTone(int channel, int eventCode, bool outOfBand,
247 : int lengthMs, int attenuationDb) override;
248 :
249 : private:
250 : WebrtcAudioConduit(const WebrtcAudioConduit& other) = delete;
251 : void operator=(const WebrtcAudioConduit& other) = delete;
252 :
253 : //Local database of currently applied receive codecs
254 : typedef std::vector<AudioCodecConfig* > RecvCodecList;
255 :
256 : //Function to convert between WebRTC and Conduit codec structures
257 : bool CodecConfigToWebRTCCodec(const AudioCodecConfig* codecInfo,
258 : webrtc::CodecInst& cinst);
259 :
260 : //Checks if given sampling frequency is supported
261 : bool IsSamplingFreqSupported(int freq) const;
262 :
263 : //Generate block size in sample lenght for a given sampling frequency
264 : unsigned int GetNum10msSamplesForFrequency(int samplingFreqHz) const;
265 :
266 : // Function to copy a codec structure to Conduit's database
267 : bool CopyCodecToDB(const AudioCodecConfig* codecInfo);
268 :
269 : // Functions to verify if the codec passed is already in
270 : // conduits database
271 : bool CheckCodecForMatch(const AudioCodecConfig* codecInfo) const;
272 : bool CheckCodecsForMatch(const AudioCodecConfig* curCodecConfig,
273 : const AudioCodecConfig* codecInfo) const;
274 : //Checks the codec to be applied
275 : MediaConduitErrorCode ValidateCodecConfig(const AudioCodecConfig* codecInfo, bool send);
276 :
277 : //Utility function to dump recv codec database
278 : void DumpCodecDB() const;
279 :
280 : webrtc::VoiceEngine* mVoiceEngine;
281 : mozilla::ReentrantMonitor mTransportMonitor;
282 : RefPtr<TransportInterface> mTransmitterTransport;
283 : RefPtr<TransportInterface> mReceiverTransport;
284 : ScopedCustomReleasePtr<webrtc::VoENetwork> mPtrVoENetwork;
285 : ScopedCustomReleasePtr<webrtc::VoEBase> mPtrVoEBase;
286 : ScopedCustomReleasePtr<webrtc::VoECodec> mPtrVoECodec;
287 : ScopedCustomReleasePtr<webrtc::VoEExternalMedia> mPtrVoEXmedia;
288 : ScopedCustomReleasePtr<webrtc::VoEAudioProcessing> mPtrVoEProcessing;
289 : ScopedCustomReleasePtr<webrtc::VoEVideoSync> mPtrVoEVideoSync;
290 : ScopedCustomReleasePtr<webrtc::VoERTP_RTCP> mPtrVoERTP_RTCP;
291 : ScopedCustomReleasePtr<webrtc::VoERTP_RTCP> mPtrRTP;
292 : //engine states of our interets
293 : mozilla::Atomic<bool> mEngineTransmitting; // If true => VoiceEngine Send-subsystem is up
294 : mozilla::Atomic<bool> mEngineReceiving; // If true => VoiceEngine Receive-subsystem is up
295 : // and playout is enabled
296 : // Keep track of each inserted RTP block and the time it was inserted
297 : // so we can estimate the clock time for a specific TimeStamp coming out
298 : // (for when we send data to MediaStreamTracks). Blocks are aged out as needed.
299 : struct Processing {
300 : TimeStamp mTimeStamp;
301 : uint32_t mRTPTimeStamp; // RTP timestamps received
302 : };
303 : AutoTArray<Processing,8> mProcessing;
304 :
305 : int mChannel;
306 : std::unique_ptr<webrtc::voe::ChannelProxy> mChannelProxy;
307 : bool mDtmfEnabled;
308 : RecvCodecList mRecvCodecList;
309 :
310 : Mutex mCodecMutex; // protects mCurSendCodecConfig
311 : nsAutoPtr<AudioCodecConfig> mCurSendCodecConfig;
312 :
313 : // Current "capture" delay (really output plus input delay)
314 : int32_t mCaptureDelay;
315 :
316 : uint32_t mLastTimestamp;
317 :
318 : uint32_t mSamples;
319 : uint32_t mLastSyncLog;
320 : };
321 :
322 : } // end namespace
323 :
324 : #endif
|