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 #include "webrtc/system_wrappers/include/critical_section_wrapper.h"
12 #include "webrtc/system_wrappers/include/file_wrapper.h"
13 #include "webrtc/system_wrappers/include/trace.h"
14 #include "webrtc/voice_engine/include/voe_errors.h"
15 #include "webrtc/voice_engine/voe_rtp_rtcp_impl.h"
16 #include "webrtc/voice_engine/voice_engine_impl.h"
17 
18 #include "webrtc/voice_engine/channel.h"
19 #include "webrtc/voice_engine/transmit_mixer.h"
20 
21 namespace webrtc {
22 
GetInterface(VoiceEngine * voiceEngine)23 VoERTP_RTCP* VoERTP_RTCP::GetInterface(VoiceEngine* voiceEngine) {
24 #ifndef WEBRTC_VOICE_ENGINE_RTP_RTCP_API
25   return NULL;
26 #else
27   if (NULL == voiceEngine) {
28     return NULL;
29   }
30   VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
31   s->AddRef();
32   return s;
33 #endif
34 }
35 
36 #ifdef WEBRTC_VOICE_ENGINE_RTP_RTCP_API
37 
VoERTP_RTCPImpl(voe::SharedData * shared)38 VoERTP_RTCPImpl::VoERTP_RTCPImpl(voe::SharedData* shared) : _shared(shared) {
39   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
40                "VoERTP_RTCPImpl::VoERTP_RTCPImpl() - ctor");
41 }
42 
~VoERTP_RTCPImpl()43 VoERTP_RTCPImpl::~VoERTP_RTCPImpl() {
44   WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
45                "VoERTP_RTCPImpl::~VoERTP_RTCPImpl() - dtor");
46 }
47 
SetLocalSSRC(int channel,unsigned int ssrc)48 int VoERTP_RTCPImpl::SetLocalSSRC(int channel, unsigned int ssrc) {
49   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
50                "SetLocalSSRC(channel=%d, %lu)", channel, ssrc);
51   if (!_shared->statistics().Initialized()) {
52     _shared->SetLastError(VE_NOT_INITED, kTraceError);
53     return -1;
54   }
55   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
56   voe::Channel* channelPtr = ch.channel();
57   if (channelPtr == NULL) {
58     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
59                           "SetLocalSSRC() failed to locate channel");
60     return -1;
61   }
62   return channelPtr->SetLocalSSRC(ssrc);
63 }
64 
GetLocalSSRC(int channel,unsigned int & ssrc)65 int VoERTP_RTCPImpl::GetLocalSSRC(int channel, unsigned int& ssrc) {
66   if (!_shared->statistics().Initialized()) {
67     _shared->SetLastError(VE_NOT_INITED, kTraceError);
68     return -1;
69   }
70   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
71   voe::Channel* channelPtr = ch.channel();
72   if (channelPtr == NULL) {
73     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
74                           "GetLocalSSRC() failed to locate channel");
75     return -1;
76   }
77   return channelPtr->GetLocalSSRC(ssrc);
78 }
79 
GetRemoteSSRC(int channel,unsigned int & ssrc)80 int VoERTP_RTCPImpl::GetRemoteSSRC(int channel, unsigned int& ssrc) {
81   if (!_shared->statistics().Initialized()) {
82     _shared->SetLastError(VE_NOT_INITED, kTraceError);
83     return -1;
84   }
85   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
86   voe::Channel* channelPtr = ch.channel();
87   if (channelPtr == NULL) {
88     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
89                           "GetRemoteSSRC() failed to locate channel");
90     return -1;
91   }
92   return channelPtr->GetRemoteSSRC(ssrc);
93 }
94 
SetSendAudioLevelIndicationStatus(int channel,bool enable,unsigned char id)95 int VoERTP_RTCPImpl::SetSendAudioLevelIndicationStatus(int channel,
96                                                        bool enable,
97                                                        unsigned char id) {
98   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
99                "SetSendAudioLevelIndicationStatus(channel=%d, enable=%d,"
100                " ID=%u)",
101                channel, enable, id);
102   if (!_shared->statistics().Initialized()) {
103     _shared->SetLastError(VE_NOT_INITED, kTraceError);
104     return -1;
105   }
106   if (enable && (id < kVoiceEngineMinRtpExtensionId ||
107                  id > kVoiceEngineMaxRtpExtensionId)) {
108     // [RFC5285] The 4-bit id is the local identifier of this element in
109     // the range 1-14 inclusive.
110     _shared->SetLastError(
111         VE_INVALID_ARGUMENT, kTraceError,
112         "SetSendAudioLevelIndicationStatus() invalid ID parameter");
113     return -1;
114   }
115 
116   // Set state and id for the specified channel.
117   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
118   voe::Channel* channelPtr = ch.channel();
119   if (channelPtr == NULL) {
120     _shared->SetLastError(
121         VE_CHANNEL_NOT_VALID, kTraceError,
122         "SetSendAudioLevelIndicationStatus() failed to locate channel");
123     return -1;
124   }
125   return channelPtr->SetSendAudioLevelIndicationStatus(enable, id);
126 }
127 
SetReceiveAudioLevelIndicationStatus(int channel,bool enable,unsigned char id)128 int VoERTP_RTCPImpl::SetReceiveAudioLevelIndicationStatus(int channel,
129                                                           bool enable,
130                                                           unsigned char id) {
131   WEBRTC_TRACE(
132       kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
133       "SetReceiveAudioLevelIndicationStatus(channel=%d, enable=%d, id=%u)",
134       channel, enable, id);
135   if (!_shared->statistics().Initialized()) {
136     _shared->SetLastError(VE_NOT_INITED, kTraceError);
137     return -1;
138   }
139   if (enable && (id < kVoiceEngineMinRtpExtensionId ||
140                  id > kVoiceEngineMaxRtpExtensionId)) {
141     // [RFC5285] The 4-bit id is the local identifier of this element in
142     // the range 1-14 inclusive.
143     _shared->SetLastError(
144         VE_INVALID_ARGUMENT, kTraceError,
145         "SetReceiveAbsoluteSenderTimeStatus() invalid id parameter");
146     return -1;
147   }
148   // Set state and id for the specified channel.
149   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
150   voe::Channel* channel_ptr = ch.channel();
151   if (channel_ptr == NULL) {
152     _shared->SetLastError(
153         VE_CHANNEL_NOT_VALID, kTraceError,
154         "SetReceiveAudioLevelIndicationStatus() failed to locate channel");
155     return -1;
156   }
157   return channel_ptr->SetReceiveAudioLevelIndicationStatus(enable, id);
158 }
159 
SetSendAbsoluteSenderTimeStatus(int channel,bool enable,unsigned char id)160 int VoERTP_RTCPImpl::SetSendAbsoluteSenderTimeStatus(int channel,
161                                                      bool enable,
162                                                      unsigned char id) {
163   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
164                "SetSendAbsoluteSenderTimeStatus(channel=%d, enable=%d, id=%u)",
165                channel, enable, id);
166   if (!_shared->statistics().Initialized()) {
167     _shared->SetLastError(VE_NOT_INITED, kTraceError);
168     return -1;
169   }
170   if (enable && (id < kVoiceEngineMinRtpExtensionId ||
171                  id > kVoiceEngineMaxRtpExtensionId)) {
172     // [RFC5285] The 4-bit id is the local identifier of this element in
173     // the range 1-14 inclusive.
174     _shared->SetLastError(
175         VE_INVALID_ARGUMENT, kTraceError,
176         "SetSendAbsoluteSenderTimeStatus() invalid id parameter");
177     return -1;
178   }
179   // Set state and id for the specified channel.
180   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
181   voe::Channel* channelPtr = ch.channel();
182   if (channelPtr == NULL) {
183     _shared->SetLastError(
184         VE_CHANNEL_NOT_VALID, kTraceError,
185         "SetSendAbsoluteSenderTimeStatus() failed to locate channel");
186     return -1;
187   }
188   return channelPtr->SetSendAbsoluteSenderTimeStatus(enable, id);
189 }
190 
SetReceiveAbsoluteSenderTimeStatus(int channel,bool enable,unsigned char id)191 int VoERTP_RTCPImpl::SetReceiveAbsoluteSenderTimeStatus(int channel,
192                                                         bool enable,
193                                                         unsigned char id) {
194   WEBRTC_TRACE(
195       kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
196       "SetReceiveAbsoluteSenderTimeStatus(channel=%d, enable=%d, id=%u)",
197       channel, enable, id);
198   if (!_shared->statistics().Initialized()) {
199     _shared->SetLastError(VE_NOT_INITED, kTraceError);
200     return -1;
201   }
202   if (enable && (id < kVoiceEngineMinRtpExtensionId ||
203                  id > kVoiceEngineMaxRtpExtensionId)) {
204     // [RFC5285] The 4-bit id is the local identifier of this element in
205     // the range 1-14 inclusive.
206     _shared->SetLastError(
207         VE_INVALID_ARGUMENT, kTraceError,
208         "SetReceiveAbsoluteSenderTimeStatus() invalid id parameter");
209     return -1;
210   }
211   // Set state and id for the specified channel.
212   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
213   voe::Channel* channelPtr = ch.channel();
214   if (channelPtr == NULL) {
215     _shared->SetLastError(
216         VE_CHANNEL_NOT_VALID, kTraceError,
217         "SetReceiveAbsoluteSenderTimeStatus() failed to locate channel");
218     return -1;
219   }
220   return channelPtr->SetReceiveAbsoluteSenderTimeStatus(enable, id);
221 }
222 
SetRTCPStatus(int channel,bool enable)223 int VoERTP_RTCPImpl::SetRTCPStatus(int channel, bool enable) {
224   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
225                "SetRTCPStatus(channel=%d, enable=%d)", channel, enable);
226   if (!_shared->statistics().Initialized()) {
227     _shared->SetLastError(VE_NOT_INITED, kTraceError);
228     return -1;
229   }
230   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
231   voe::Channel* channelPtr = ch.channel();
232   if (channelPtr == NULL) {
233     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
234                           "SetRTCPStatus() failed to locate channel");
235     return -1;
236   }
237   channelPtr->SetRTCPStatus(enable);
238   return 0;
239 }
240 
GetRTCPStatus(int channel,bool & enabled)241 int VoERTP_RTCPImpl::GetRTCPStatus(int channel, bool& enabled) {
242   if (!_shared->statistics().Initialized()) {
243     _shared->SetLastError(VE_NOT_INITED, kTraceError);
244     return -1;
245   }
246   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
247   voe::Channel* channelPtr = ch.channel();
248   if (channelPtr == NULL) {
249     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
250                           "GetRTCPStatus() failed to locate channel");
251     return -1;
252   }
253   return channelPtr->GetRTCPStatus(enabled);
254 }
255 
SetRTCP_CNAME(int channel,const char cName[256])256 int VoERTP_RTCPImpl::SetRTCP_CNAME(int channel, const char cName[256]) {
257   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
258                "SetRTCP_CNAME(channel=%d, cName=%s)", channel, cName);
259   if (!_shared->statistics().Initialized()) {
260     _shared->SetLastError(VE_NOT_INITED, kTraceError);
261     return -1;
262   }
263   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
264   voe::Channel* channelPtr = ch.channel();
265   if (channelPtr == NULL) {
266     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
267                           "SetRTCP_CNAME() failed to locate channel");
268     return -1;
269   }
270   return channelPtr->SetRTCP_CNAME(cName);
271 }
272 
GetRemoteRTCP_CNAME(int channel,char cName[256])273 int VoERTP_RTCPImpl::GetRemoteRTCP_CNAME(int channel, char cName[256]) {
274   if (!_shared->statistics().Initialized()) {
275     _shared->SetLastError(VE_NOT_INITED, kTraceError);
276     return -1;
277   }
278   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
279   voe::Channel* channelPtr = ch.channel();
280   if (channelPtr == NULL) {
281     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
282                           "GetRemoteRTCP_CNAME() failed to locate channel");
283     return -1;
284   }
285   return channelPtr->GetRemoteRTCP_CNAME(cName);
286 }
287 
GetRemoteRTCPData(int channel,unsigned int & NTPHigh,unsigned int & NTPLow,unsigned int & timestamp,unsigned int & playoutTimestamp,unsigned int * jitter,unsigned short * fractionLost)288 int VoERTP_RTCPImpl::GetRemoteRTCPData(
289     int channel,
290     unsigned int& NTPHigh,           // from sender info in SR
291     unsigned int& NTPLow,            // from sender info in SR
292     unsigned int& timestamp,         // from sender info in SR
293     unsigned int& playoutTimestamp,  // derived locally
294     unsigned int* jitter,            // from report block 1 in SR/RR
295     unsigned short* fractionLost)    // from report block 1 in SR/RR
296 {
297   if (!_shared->statistics().Initialized()) {
298     _shared->SetLastError(VE_NOT_INITED, kTraceError);
299     return -1;
300   }
301   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
302   voe::Channel* channelPtr = ch.channel();
303   if (channelPtr == NULL) {
304     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
305                           "GetRemoteRTCP_CNAME() failed to locate channel");
306     return -1;
307   }
308   return channelPtr->GetRemoteRTCPData(NTPHigh, NTPLow, timestamp,
309                                        playoutTimestamp, jitter, fractionLost);
310 }
311 
GetRTPStatistics(int channel,unsigned int & averageJitterMs,unsigned int & maxJitterMs,unsigned int & discardedPackets)312 int VoERTP_RTCPImpl::GetRTPStatistics(int channel,
313                                       unsigned int& averageJitterMs,
314                                       unsigned int& maxJitterMs,
315                                       unsigned int& discardedPackets) {
316   if (!_shared->statistics().Initialized()) {
317     _shared->SetLastError(VE_NOT_INITED, kTraceError);
318     return -1;
319   }
320   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
321   voe::Channel* channelPtr = ch.channel();
322   if (channelPtr == NULL) {
323     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
324                           "GetRTPStatistics() failed to locate channel");
325     return -1;
326   }
327   return channelPtr->GetRTPStatistics(averageJitterMs, maxJitterMs,
328                                       discardedPackets);
329 }
330 
GetRTCPStatistics(int channel,CallStatistics & stats)331 int VoERTP_RTCPImpl::GetRTCPStatistics(int channel, CallStatistics& stats) {
332   if (!_shared->statistics().Initialized()) {
333     _shared->SetLastError(VE_NOT_INITED, kTraceError);
334     return -1;
335   }
336   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
337   voe::Channel* channelPtr = ch.channel();
338   if (channelPtr == NULL) {
339     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
340                           "GetRTPStatistics() failed to locate channel");
341     return -1;
342   }
343   return channelPtr->GetRTPStatistics(stats);
344 }
345 
GetRemoteRTCPReportBlocks(int channel,std::vector<ReportBlock> * report_blocks)346 int VoERTP_RTCPImpl::GetRemoteRTCPReportBlocks(
347     int channel, std::vector<ReportBlock>* report_blocks) {
348   if (!_shared->statistics().Initialized()) {
349     _shared->SetLastError(VE_NOT_INITED, kTraceError);
350     return -1;
351   }
352   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
353   voe::Channel* channel_ptr = ch.channel();
354   if (channel_ptr == NULL) {
355     _shared->SetLastError(
356         VE_CHANNEL_NOT_VALID, kTraceError,
357         "GetRemoteRTCPReportBlocks() failed to locate channel");
358     return -1;
359   }
360   return channel_ptr->GetRemoteRTCPReportBlocks(report_blocks);
361 }
362 
SetREDStatus(int channel,bool enable,int redPayloadtype)363 int VoERTP_RTCPImpl::SetREDStatus(int channel,
364                                   bool enable,
365                                   int redPayloadtype) {
366   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
367                "SetREDStatus(channel=%d, enable=%d, redPayloadtype=%d)",
368                channel, enable, redPayloadtype);
369 #ifdef WEBRTC_CODEC_RED
370   if (!_shared->statistics().Initialized()) {
371     _shared->SetLastError(VE_NOT_INITED, kTraceError);
372     return -1;
373   }
374   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
375   voe::Channel* channelPtr = ch.channel();
376   if (channelPtr == NULL) {
377     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
378                           "SetREDStatus() failed to locate channel");
379     return -1;
380   }
381   return channelPtr->SetREDStatus(enable, redPayloadtype);
382 #else
383   _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
384                         "SetREDStatus() RED is not supported");
385   return -1;
386 #endif
387 }
388 
GetREDStatus(int channel,bool & enabled,int & redPayloadtype)389 int VoERTP_RTCPImpl::GetREDStatus(int channel,
390                                   bool& enabled,
391                                   int& redPayloadtype) {
392 #ifdef WEBRTC_CODEC_RED
393   if (!_shared->statistics().Initialized()) {
394     _shared->SetLastError(VE_NOT_INITED, kTraceError);
395     return -1;
396   }
397   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
398   voe::Channel* channelPtr = ch.channel();
399   if (channelPtr == NULL) {
400     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
401                           "GetREDStatus() failed to locate channel");
402     return -1;
403   }
404   return channelPtr->GetREDStatus(enabled, redPayloadtype);
405 #else
406   _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
407                         "GetREDStatus() RED is not supported");
408   return -1;
409 #endif
410 }
411 
SetNACKStatus(int channel,bool enable,int maxNoPackets)412 int VoERTP_RTCPImpl::SetNACKStatus(int channel, bool enable, int maxNoPackets) {
413   WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
414                "SetNACKStatus(channel=%d, enable=%d, maxNoPackets=%d)", channel,
415                enable, maxNoPackets);
416 
417   voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
418   voe::Channel* channelPtr = ch.channel();
419   if (channelPtr == NULL) {
420     _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
421                           "SetNACKStatus() failed to locate channel");
422     return -1;
423   }
424   channelPtr->SetNACKStatus(enable, maxNoPackets);
425   return 0;
426 }
427 
428 #endif  // #ifdef WEBRTC_VOICE_ENGINE_RTP_RTCP_API
429 
430 }  // namespace webrtc
431